package com.hjieli.config.security.oauth;

import java.io.IOException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.client.resource.BaseOAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.provider.error.DefaultWebResponseExceptionTranslator;
import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint;
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

@Component
public class AuthExceptionEntryPoint extends OAuth2AuthenticationEntryPoint {
	private static Logger logger = LoggerFactory.getLogger(AuthExceptionEntryPoint.class);
	

	@Value("${security.oauth2.client.access-token-uri}")
    private String accessTokenUri;
	
    @Value("${security.oauth2.client.client-id}")
    private String clientId;

    @Value("${security.oauth2.client.client-secret}")
    private String clientSecret;
    
    private WebResponseExceptionTranslator<?> exceptionTranslator = new DefaultWebResponseExceptionTranslator();
  
    @Autowired
    RestTemplate restTemplate;
    
	@Override
	public void commence(HttpServletRequest request, HttpServletResponse response,
			AuthenticationException authException) throws IOException, ServletException {
		// TODO Auto-generated method stub

		try {
            //解析异常，如果是401则处理
			String url = request.getRequestURI();
            ResponseEntity<?> result = exceptionTranslator.translate(authException);
            if (result.getStatusCode() == HttpStatus.UNAUTHORIZED) {
                MultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>();
                formData.add("client_id", clientId);
                formData.add("client_secret", clientSecret);
                formData.add("grant_type", "refresh_token");
                Cookie[] cookie=request.getCookies();
                for(Cookie coo:cookie){
                    if(coo.getName().equals("x-refresh-token")){
                        formData.add("refresh_token", coo.getValue());
                    }
                }
                
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
                headers.remove(HttpHeaders.AUTHORIZATION);
                Map map = restTemplate.exchange(accessTokenUri, HttpMethod.POST,
                            new HttpEntity<MultiValueMap<String, String>>(formData, headers), Map.class).getBody();
                //如果刷新异常,则进一步处理
                if(map.get("error")!=null){
                    //如果是网页,跳转到登陆页面
                    response.sendRedirect("/login");
                }else{
                    //如果刷新成功则存储cookie并且跳转到原来需要访问的页面
                    
                    Cookie tokenCookie = new Cookie("x-token", map.get("access_token").toString());
                    tokenCookie.setPath("/");
                    tokenCookie.setMaxAge(60 * 60 * 2);

                    Cookie refreshTokenCookie = new Cookie("x-refresh-token", map.get("refresh_token").toString());
                    refreshTokenCookie.setPath("/");
                    refreshTokenCookie.setMaxAge(60 * 60 * 2);
                    
                    response.addCookie(tokenCookie);
                    response.addCookie(refreshTokenCookie);
                    response.setHeader("Authorization", "bearer" + map.get("access_token").toString());
                    response.sendRedirect(request.getRequestURI());
                }
            }else{
                //如果不是401异常，则以默认的方法继续处理其他异常
                super.commence(request,response,authException);
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.toString());
            response.sendRedirect("/login");
        }

	}

}
